home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung 2 / Power-Programmierung CD 2 (Tewi)(1994).iso / gnu / djgpp / src / gas-211 / gas / as.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-05-30  |  11.8 KB  |  472 lines

  1. /* as.c - GAS main program.
  2.    Copyright (C) 1987, 1990, 1991, 1992 Free Software Foundation, Inc.
  3.  
  4.    This file is part of GAS, the GNU Assembler.
  5.  
  6.    GAS is free software; you can redistribute it and/or modify
  7.    it under the terms of the GNU General Public License as published by
  8.    the Free Software Foundation; either version 2, or (at your option)
  9.    any later version.
  10.  
  11.    GAS is distributed in the hope that it will be useful,
  12.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.    GNU General Public License for more details.
  15.  
  16.    You should have received a copy of the GNU General Public License
  17.    along with GAS; see the file COPYING.  If not, write to
  18.    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
  19.  
  20. /*
  21.  * Main program for AS; a 32-bit assembler of GNU.
  22.  * Understands command arguments.
  23.  * Has a few routines that don't fit in other modules because they
  24.  * are shared.
  25.  *
  26.  *
  27.  *            bugs
  28.  *
  29.  * : initialisers
  30.  *    Since no-one else says they will support them in future: I
  31.  * don't support them now.
  32.  *
  33.  */
  34.  
  35. #include <stdio.h>
  36. #include <string.h>
  37.  
  38. #ifdef _POSIX_SOURCE
  39. #include <sys/types.h>        /* For pid_t in signal.h */
  40. #endif
  41. #include <signal.h>
  42.  
  43. #define COMMON
  44.  
  45. #include "as.h"
  46. #include "config.h"
  47. #include "subsegs.h"
  48.  
  49. #if __STDC__ == 1
  50.  
  51. /* This prototype for got_sig() is ansi.  If you want
  52.    anything else, then your compiler is lying to you when
  53.    it says that it is __STDC__.  If you want to change it,
  54.    #ifdef protect it from those of us with real ansi
  55.    compilers. */
  56.  
  57. #define SIGTY void
  58.  
  59. static void got_sig (int sig);
  60. static void perform_an_assembly_pass (int argc, char **argv);
  61.  
  62. #else /* __STDC__ */
  63.  
  64. #ifndef SIGTY
  65. #define SIGTY int
  66. #endif
  67.  
  68. static SIGTY got_sig ();
  69. static void perform_an_assembly_pass ();
  70.  
  71. #endif /* not __STDC__ */
  72.  
  73. #ifndef EXIT_SUCCESS
  74. #define EXIT_SUCCESS 0
  75. #define EXIT_FAILURE 1
  76. #endif
  77.  
  78. int listing;            /* true if a listing is wanted */
  79.  
  80. char *myname;            /* argv[0] */
  81. #ifdef BFD_ASSEMBLER
  82. segT big_section, reg_section, pass1_section;
  83. segT diff_section, absent_section;
  84. segT text_section, data_section, bss_section;
  85. #endif
  86.  
  87. int 
  88. main (argc, argv)
  89.      int argc;
  90.      char **argv;
  91. {
  92.   int work_argc;        /* variable copy of argc */
  93.   char **work_argv;        /* variable copy of argv */
  94.   char *arg;            /* an arg to program */
  95.   char a;            /* an arg flag (after -) */
  96.  
  97. #if 0 /* do we need any of this?? */
  98.   {
  99.     static const int sig[] = {SIGHUP, SIGINT, SIGPIPE, SIGTERM, 0};
  100.  
  101.     for (a = 0; sig[a] != 0; a++)
  102.       if (signal (sig[a], SIG_IGN) != SIG_IGN)
  103.     signal (sig[a], got_sig);
  104.   }
  105. #endif
  106.  
  107.   myname = argv[0];
  108.   memset (flagseen, '\0', sizeof (flagseen));    /* aint seen nothing yet */
  109. #ifndef OBJ_DEFAULT_OUTPUT_FILE_NAME
  110. #define OBJ_DEFAULT_OUTPUT_FILE_NAME "a.out"
  111. #endif
  112.   out_file_name = OBJ_DEFAULT_OUTPUT_FILE_NAME;
  113.  
  114. #ifdef BFD_ASSEMBLER
  115.   bfd_init ();
  116. #endif
  117.  
  118.   symbol_begin ();
  119.   subsegs_begin ();
  120.   read_begin ();
  121.   input_scrub_begin ();
  122.   frag_init ();
  123.   /*
  124.    * Parse arguments, but we are only interested in flags.
  125.    * When we find a flag, we process it then make it's argv[] NULL.
  126.    * This helps any future argv[] scanners avoid what we processed.
  127.    * Since it is easy to do here we interpret the special arg "-"
  128.    * to mean "use stdin" and we set that argv[] pointing to "".
  129.    * After we have munged argv[], the only things left are source file
  130.    * name(s) and ""(s) denoting stdin. These file names are used
  131.    * (perhaps more than once) later.
  132.    */
  133.   /* FIXME-SOMEDAY this should use getopt. */
  134.   work_argc = argc - 1;        /* don't count argv[0] */
  135.   work_argv = argv + 1;        /* skip argv[0] */
  136.   for (; work_argc--; work_argv++)
  137.     {
  138.       arg = *work_argv;        /* work_argv points to this argument */
  139.  
  140.       if (*arg != '-')        /* Filename. We need it later. */
  141.     continue;        /* Keep scanning args looking for flags. */
  142.       if (arg[1] == '-' && arg[2] == 0)
  143.     {
  144.       /* "--" as an argument means read STDIN */
  145.       /* on this scan, we don't want to think about filenames */
  146.       *work_argv = "";    /* Code that means 'use stdin'. */
  147.       continue;
  148.     }
  149.       /* This better be a switch. */
  150.       arg++;            /*->letter. */
  151.  
  152.       while ((a = *arg) != '\0')
  153.     {            /* scan all the 1-char flags */
  154.       arg++;        /* arg->after letter. */
  155.       a &= 0x7F;        /* ascii only please */
  156.       flagseen[a] = 1;
  157.       switch (a)
  158.         {
  159.         case 'a':
  160.           {
  161.         int loop = 1;
  162.  
  163.         while (loop)
  164.           {
  165.             switch (*arg)
  166.               {
  167.               case 'l':
  168.             listing |= LISTING_LISTING;
  169.             arg++;
  170.             break;
  171.               case 's':
  172.             listing |= LISTING_SYMBOLS;
  173.             arg++;
  174.             break;
  175.               case 'h':
  176.             listing |= LISTING_HLL;
  177.             arg++;
  178.             break;
  179.  
  180.               case 'n':
  181.             listing |= LISTING_NOFORM;
  182.             arg++;
  183.             break;
  184.               case 'd':
  185.             listing |= LISTING_NODEBUG;
  186.             arg++;
  187.             break;
  188.               default:
  189.             if (!listing)
  190.               listing = LISTING_DEFAULT;
  191.             loop = 0;
  192.             break;
  193.               }
  194.           }
  195.           }
  196.  
  197.           break;
  198.  
  199.  
  200.         case 'f':
  201.           break;        /* -f means fast - no need for "app" preprocessor. */
  202.  
  203.         case 'D':
  204.           /* DEBUG is implemented: it debugs different */
  205.           /* things to other people's assemblers. */
  206.           break;
  207.  
  208.         case 'I':
  209.           {            /* Include file directory */
  210.  
  211.         char *temp = NULL;
  212.         if (*arg)
  213.           {
  214.             temp = strdup (arg);
  215.             if (!temp)
  216.               as_fatal ("virtual memory exhuasted");
  217.           }
  218.         else if (work_argc)
  219.           {
  220.             *work_argv = NULL;
  221.             work_argc--;
  222.             temp = *++work_argv;
  223.           }
  224.         else
  225.           as_warn ("%s: I expected a filename after -I", myname);
  226.         add_include_dir (temp);
  227.         arg = "";    /* Finished with this arg. */
  228.         break;
  229.           }
  230.  
  231. #ifdef WARN_SIGNED_OVERFLOW_WORD
  232.           /* Don't warn about signed overflow.  */
  233.         case 'J':
  234.           break;
  235. #endif
  236.  
  237. #ifndef WORKING_DOT_WORD
  238.         case 'K':
  239.           break;
  240. #endif
  241.  
  242.         case 'L':        /* -L means keep L* symbols */
  243.           break;
  244.  
  245.         case 'o':
  246.           if (*arg)        /* Rest of argument is object file-name. */
  247.         {
  248.           out_file_name = strdup (arg);
  249.           if (!out_file_name)
  250.             as_fatal ("virtual memory exhausted");
  251.         }
  252.           else if (work_argc)
  253.         {        /* Want next arg for a file-name. */
  254.           *work_argv = NULL;    /* This is not a file-name. */
  255.           work_argc--;
  256.           out_file_name = *++work_argv;
  257.         }
  258.           else
  259.         as_warn ("%s: I expected a filename after -o. \"%s\" assumed.",
  260.              myname, out_file_name);
  261.           arg = "";        /* Finished with this arg. */
  262.           break;
  263.  
  264.         case 'R':
  265.           /* -R means put data into text segment */
  266.           flag_readonly_data_in_text = 1;
  267.           break;
  268.  
  269.         case 'v':
  270. #ifdef    VMS
  271.           {
  272.         extern char *compiler_version_string;
  273.         compiler_version_string = arg;
  274.           }
  275. #else /* not VMS */
  276.           if (*arg && strcmp (arg, "ersion"))
  277.         {
  278.           as_warn ("Unknown -v option ignored");
  279.           arg += strlen (arg);
  280.           break;
  281.         }
  282.  
  283.           fprintf (stderr, "GNU assembler version %s (%s)",
  284.                GAS_VERSION, TARGET_ALIAS);
  285. #ifdef BFD_ASSEMBLER
  286.           fprintf (stderr, ", using BFD version %s", BFD_VERSION);
  287. #endif
  288.           fprintf (stderr, "\n");
  289. #endif /* not VMS */
  290.           while (*arg)
  291.         arg++;        /* Skip the rest */
  292.           break;
  293.  
  294.         case 'W':
  295.           /* -W means don't warn about things */
  296.           flag_suppress_warnings = 1;
  297.           break;
  298.  
  299.         case 'w':
  300.         case 'X':
  301.           /* -X means treat warnings as errors */
  302.           break;
  303.         case 'Z':
  304.           /* -Z means attempt to generate object file even after errors. */
  305.           flag_always_generate_output = 1;
  306.           break;
  307.  
  308.         default:
  309.           --arg;
  310.           if (md_parse_option (&arg, &work_argc, &work_argv) == 0)
  311.         as_warn ("%s: I don't understand '%c' flag.", myname, a);
  312.           if (arg && *arg)
  313.         arg++;
  314.           break;
  315.         }
  316.     }
  317.       /*
  318.        * We have just processed a "-..." arg, which was not a
  319.        * file-name. Smash it so the
  320.        * things that look for filenames won't ever see it.
  321.        *
  322.        * Whatever work_argv points to, it has already been used
  323.        * as part of a flag, so DON'T re-use it as a filename.
  324.        */
  325.       *work_argv = NULL;    /* NULL means 'not a file-name' */
  326.     }
  327.  
  328. #ifdef BFD_ASSEMBLER
  329.   output_file_create (out_file_name);
  330.   assert (stdoutput != 0);
  331. #endif
  332.  
  333.   /* Here with flags set up in flagseen[]. */
  334.   perform_an_assembly_pass (argc, argv);    /* Assemble it. */
  335. #ifdef TC_I960
  336.   brtab_emit ();
  337. #endif
  338.   if (seen_at_least_1_file ()
  339.       && !((had_warnings () && flag_always_generate_output)
  340.        || had_errors () > 0))
  341.     {
  342.       write_object_file ();    /* relax() addresses then emit object file */
  343.     }                /* we also check in write_object_file() just before emit. */
  344. #ifdef BFD_ASSEMBLER
  345.   else
  346.     {
  347.       output_file_close (out_file_name);
  348.       unlink (out_file_name);
  349.     }
  350. #endif
  351.  
  352.   input_scrub_end ();
  353.   md_end ();            /* MACHINE.c */
  354.  
  355. #ifndef NO_LISTING
  356.   listing_print ("");
  357. #endif
  358.  
  359.   if ((had_warnings () && flagseen['Z'])
  360.       || had_errors () > 0)
  361.     return EXIT_FAILURE;
  362.   return EXIT_SUCCESS;
  363. }
  364.  
  365.  
  366. /*            perform_an_assembly_pass()
  367.  *
  368.  * Here to attempt 1 pass over each input file.
  369.  * We scan argv[*] looking for filenames or exactly "" which is
  370.  * shorthand for stdin. Any argv that is NULL is not a file-name.
  371.  * We set need_pass_2 TRUE if, after this, we still have unresolved
  372.  * expressions of the form (unknown value)+-(unknown value).
  373.  *
  374.  * Note the un*x semantics: there is only 1 logical input file, but it
  375.  * may be a catenation of many 'physical' input files.
  376.  */
  377. static void 
  378. perform_an_assembly_pass (argc, argv)
  379.      int argc;
  380.      char **argv;
  381. {
  382.   int saw_a_file = 0;
  383.   unsigned int i;
  384. #ifdef BFD_ASSEMBLER
  385.   flagword applicable;
  386. #endif
  387.  
  388.   need_pass_2 = 0;
  389.  
  390. #ifndef BFD_ASSEMBLER
  391. #ifdef MANY_SEGMENTS
  392.   for (i = SEG_E0; i < SEG_UNKNOWN; i++)
  393.     {
  394.       segment_info[i].fix_root = 0;
  395.     }
  396.   /* Create the three fixed ones */
  397.   subseg_new (SEG_E0, 0);
  398.   subseg_new (SEG_E1, 0);
  399.   subseg_new (SEG_E2, 0);
  400.   strcpy (segment_info[SEG_E0].scnhdr.s_name, ".text");
  401.   strcpy (segment_info[SEG_E1].scnhdr.s_name, ".data");
  402.   strcpy (segment_info[SEG_E2].scnhdr.s_name, ".bss");
  403.  
  404.   subseg_new (SEG_E0, 0);
  405. #else /* not MANY_SEGMENTS */
  406.   text_fix_root = NULL;
  407.   data_fix_root = NULL;
  408.   bss_fix_root = NULL;
  409.  
  410.   subseg_new (SEG_TEXT, 0);
  411. #endif /* not MANY_SEGMENTS */
  412. #else /* BFD_ASSEMBLER */
  413.   /* Create the standard sections, and those the assembler uses
  414.      internally.  */
  415.   text_section = subseg_new (".text", 0);
  416.   data_section = subseg_new (".data", 0);
  417.   bss_section = subseg_new (".bss", 0);
  418.   /* @@ FIXME -- we're setting the RELOC flag so that sections are assumed
  419.      to have relocs, otherwise we don't find out in time. */
  420.   applicable = bfd_applicable_section_flags (stdoutput);
  421.   bfd_set_section_flags (stdoutput, text_section,
  422.              applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC
  423.                        | SEC_CODE | SEC_READONLY));
  424.   /* @@ FIXME -- SEC_CODE seems to mean code only, rather than code possibly.*/
  425.   bfd_set_section_flags (stdoutput, data_section,
  426.              applicable & (SEC_ALLOC | SEC_LOAD | SEC_RELOC));
  427.   bfd_set_section_flags (stdoutput, bss_section, applicable & SEC_ALLOC);
  428.   subseg_new (BFD_ABS_SECTION_NAME, 0);
  429.   subseg_new (BFD_UND_SECTION_NAME, 0);
  430.   big_section = subseg_new ("*GAS `big' section*", 0);
  431.   reg_section = subseg_new ("*GAS `reg' section*", 0);
  432.   pass1_section = subseg_new ("*GAS `pass1' section*", 0);
  433.   diff_section = subseg_new ("*GAS `diff' section*", 0);
  434.   absent_section = subseg_new ("*GAS `absent' section*", 0);
  435.  
  436.   subseg_new (".text", 0);
  437. #endif /* BFD_ASSEMBLER */
  438.  
  439.   /* This may add symbol table entries, which requires having an open BFD,
  440.      and sections already created, in BFD_ASSEMBLER mode.  */
  441.   md_begin ();
  442.  
  443.   argv++;            /* skip argv[0] */
  444.   argc--;            /* skip argv[0] */
  445.   while (argc--)
  446.     {
  447.       if (*argv)
  448.     {            /* Is it a file-name argument? */
  449.       saw_a_file++;
  450.       /* argv->"" if stdin desired, else->filename */
  451.       read_a_source_file (*argv);
  452.     }
  453.       argv++;            /* completed that argv */
  454.     }
  455.   if (!saw_a_file)
  456.     read_a_source_file ("");
  457. }                /* perform_an_assembly_pass() */
  458.  
  459. static SIGTY
  460. got_sig (sig)
  461.      int sig;
  462. {
  463.   static here_before = 0;
  464.  
  465.   as_bad ("Interrupted by signal %d", sig);
  466.   if (here_before++)
  467.     exit (EXIT_FAILURE);
  468.   return ((SIGTY) 0);
  469. }
  470.  
  471. /* end of as.c */
  472.